iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0
Modern Web

用 Node.js 打造後端 API系列 第 4

Day 04 - 自訂錯誤處理函式

  • 分享至 

  • xImage
  •  

介紹asyncHandler


在bootcamps controller中,CRUD 函式目前都是以try & catch 來處理錯誤
我們可以透過撰寫wrapper function來簡化不停重複的try & catch block
在middleware資料夾中新增async.js file:

const asyncHandler = fn => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
}

之後再把asyncHandler包在async function外就ok了~

建立ErrorResponse Class


在昨天的CRUD API中,我們可以分為兩個部分來處理錯誤:

  • 輸入格式正確的ObjectId,但在資料庫中找不到bootcamp,return error
  • 輸入格式錯誤的ObjectId或發生其他錯誤,return error

第一種情況比較好處理,只需要新增errorResponse.js file

class ErrorResponse extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
  }
}

值得注意的是,message繼承來自Error的property
透過擴展Error,我們可以在我們創建的錯誤中獲得預先構建的功能,這些功能可能會在某些情況下需要
在'./controllers/bootcamps.js'中處理第一種情況:

if (!bootcamp) {
  return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`, 404));
}

建立errorHandler中介函式


其他常見的錯誤,我們可以再分成三種情況討論:

  • 輸入格式錯誤的ObjectId
  • POST相同的bootcamp資料
  • POST的bootcamp資料不齊全(缺少name, description...)

第一種情況,回傳的err.name會顯示為CastError

if (err.name === 'CastError') {
  const message = `Resource not found with id of ${err.value}`;
  error = new ErrorResponse(message, 404);
}

第二種情況,會回傳E11000 duplicate key error

if (err.code === 11000) {
  const message = 'Duplicate field value entered';
  error = new ErrorResponse(message, 400);
}

第三種情況為mongoose validation error,我們要的資訊是回傳err.errors object的message

if (err.name === 'ValidationError') {
  const message = Object.values(err.errors).map(val => val.message);
  error = new ErrorResponse(message, 400);
}

最後在回傳statusCode & error.message就完成啦!


上一篇
Day 03 - 建立第一組Model & CRUD功能
下一篇
Day 05 - 進階搜尋結果
系列文
用 Node.js 打造後端 API30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言